﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Common;
using Common.Views;
using System.Drawing;

namespace BusinessLogic
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IFaultsService" in both code and config file together.
    
    /// <summary>
    /// This interface contains methods found in the FaultsService which send and get data regarding faults to and
    /// from the Faults, FaultDetails, FaultStatus and FaultCategories tables in the database.
    /// </summary>
    [ServiceContract]
    public interface IFaultsService
    {
        /// <summary>
        /// A method which retrieves the status of the fault
        /// </summary>
        /// <param name="orderID">The ID of the order for which to retreive the product</param>
        /// <param name="productID">The ID of the product for which to retreive the fault status</param>
        /// <returns>A string value which represents the fault status. If there is not fault status, null is returned</returns>
        [OperationContract]
        string GetFaultsForOrder(Guid orderID, int productID);

        /// <summary>
        /// A method which retrieves a list of all the fault categories
        /// </summary>
        /// <returns>A list of fault categories</returns>
        [OperationContract]
        IEnumerable<FaultCategory> GetFaultCategories();

        /// <summary>
        /// A method which adds a new fault to the database regarding a faulty product
        /// </summary>
        /// <param name="faultId">The ID of the fault</param>
        /// <param name="faultCatId">The ID of the fault category</param>
        /// <param name="orderId">The ID of the order</param>
        /// <param name="productId">The ID of the product to report</param>
        /// <param name="details">The details of the fault</param>
        /// <param name="barcode">The barcode which was previously generated using a web service</param>
        /// <param name="username">The username of the user who is reporting a faulty product</param>
        [OperationContract]
        void AddFault(Guid faultId, int faultCatId, Guid orderId, int productId, string details, byte[] barcode, string username);
        
        /// <summary>
        /// A method which gets a list of transactions for a particular username, for a chosen product, between the chosen dates
        /// </summary>
        /// <param name="start">The start date chosen by the user</param>
        /// <param name="end">The end date chosen by the user</param>
        /// <param name="productId">The ID of the product chosen</param>
        /// <param name="username">The username for whom to get the transactions</param>
        /// <returns>A list of transactions</returns>
        [OperationContract]
        IEnumerable<OrdersView> FilterTransactions(DateTime start, DateTime end, int productId, string username);

        /// <summary>
        /// A method used to get all the faults
        /// </summary>
        /// <returns>A list of all the faults made by all users</returns>
        [OperationContract]
        IEnumerable<Fault> GetAllFaults();

        /// <summary>
        /// A method which gets log entries according to the latest first
        /// </summary>
        /// <returns>A list of log entries sorted by date</returns>
        [OperationContract]
        IEnumerable<FaultsView> SortEntriesByDate();

        /// <summary>
        /// A method which gets log entries between certain dates
        /// </summary>
        /// <param name="start">The start date from when to retrieve the log entry</param>
        /// <param name="end">The end date to when to retrieve the log entry</param>
        /// <returns>A list of log entries between two dates</returns>
        [OperationContract]
        IEnumerable<FaultsView> FilterByLogDate(DateTime start, DateTime end);

        /// <summary>
        /// A method which gets log entries according to the fault ID
        /// </summary>
        /// <param name="faultId">The ID of the fault</param>
        /// <returns>A list of log entries retrieved according to the fault ID</returns>
        [OperationContract]
        IEnumerable<FaultsView> FilterByFaultID(Guid faultId);

        /// <summary>
        /// A method which gets a log entries according to the client ID
        /// </summary>
        /// <param name="username">The ID of the client - username</param>
        /// <returns>A list of log entries for a particular user</returns>
        [OperationContract]
        IEnumerable<FaultsView> FilterByClientID(string username);

        /// <summary>
        /// A method which gets log entries according to a particular 
        /// client ID, fault ID and between two specific dates
        /// </summary>
        /// <param name="faultId">The ID of the fault for which to get the log entries</param>
        /// <param name="username">The username of the client for whom to get the log entries</param>
        /// <param name="start">The start date from when to retrieve the log entries</param>
        /// <param name="end">The end date to when to retrieve the log entries</param>
        /// <returns>A list of log entries which is filtered by the fault ID, 
        /// client ID, which is between two specified dates</returns>
        [OperationContract]
        IEnumerable<FaultsView> FilterAll(Guid faultId, string username, DateTime start, DateTime end);

        /// <summary>
        /// A method which gets all the log entries found in the database
        /// </summary>
        /// <returns>A list of all the log entries</returns>
        [OperationContract]
        IEnumerable<FaultsView> GetAllLogEntires();

        /// <summary>
        /// A method which gets all the fault statuses available in the database
        /// </summary>
        /// <returns>A list of fault statuses</returns>
        [OperationContract]
        IEnumerable<FaultStatu> GetAllFaultStatuses();

        /// <summary>
        /// A method which adds a new log entry to the database when the status of the fault for a reported product has been updated.
        /// This method also sends an SMS to the user to inform them about the update. An e-mail is also sent to the user with the update.
        /// </summary>
        /// <param name="OrderID">The ID of the order which is used to retrieve the user's email address and mobile number</param>
        /// <param name="faultID">The ID of the fault to update</param>
        /// <param name="details">The details of the fault</param>
        /// <param name="statusID">The new ID of the fault status</param>
        [OperationContract]
        void UpdateFault(Guid OrderID, Guid faultID, string details, int statusID);
    }
}
